package jaoso.framework.security.impl;

import jaoso.framework.dao.RightDAO;
import jaoso.framework.domain.Right;
import jaoso.framework.security.Acl;
import jaoso.framework.security.ProtectedResource;

import jaoso.framework.util.JaosoConfig;
import jaoso.framework.util.MyUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

/**
 * parse XML
 * 
 * @author edgeloner
 */
public class AclImpl implements Acl
{
    /** DOCUMENT ME! */
    private static Map protectedResourcesMap;

    /** DOCUMENT ME! */
    private static Collection protectedResources = new ArrayList();

    /** DOCUMENT ME! */
    private static String fileName;

    /** log */
    private static Log log = LogFactory.getLog(AclImpl.class);

    private JaosoConfig jaosoConfig;
    
    private RightDAO rightDAO;

    public void setJaosoConfig(JaosoConfig jaosoConfig)
    {
        this.jaosoConfig = jaosoConfig;
    }

    /**
     * init file path
     */
    private void initFilePath()
    {
        fileName = jaosoConfig.getSecurityConfigPath();
    }

    /**
     * Check if a uri is a protected Resource
     * 
     * @param uri
     *            url
     * @return boolean - if this uri is a protected Resource
     */
    public final boolean isProtectedResource(final String uri)
    {
        /*if (fileName == null)
        {
            init();
        }*/

        if (MyUtils.isBlank(uri))
        {
            return false;
        }

        return protectedResourcesMap.containsKey(uri);
    }

    /**
     * get ProtectedResources collection
     * 
     * @return ProtectedResources collection
     */
    public final Collection getProtectedResources()
    {
        if (fileName == null)
        {
            init();
        }

        return protectedResources;
    }

    /**
     * @param map
     *            ProtectedResources Map
     */
    public final void setProtectedResourcesMap(final Map map)
    {
        init();
        protectedResourcesMap = map;
        protectedResources = (Collection) map.get("protectedResources");
        //XMLUtils.write(protectedResources, fileName);
    }

    /**
     * check group has right for the url
     * 
     * @param url
     *            url
     * @param group
     *            group id
     * @return boolean
     */
    public final boolean hasRight(final String url, final String group)
    {
        log.info("hasRight: " + url + group);

        /*if (fileName == null)
        {
            init();
        }*/

        if (MyUtils.isBlank(url) || MyUtils.isBlank(group))
        {
            return false;
        }

        Map groups = (Map) protectedResourcesMap.get(url);

        if (groups != null)
        {
            return groups.containsKey(group);
        } else
        {
            return false;
        }
    }

    /**
     * init
     */
    private void init()
    {
        /*initFilePath();

        int i;
        File xmlFile = new File(fileName);
        Document doc = null;
        String box = null;
        String url = null;
        String desc = null;
        String property;
        String value;

        try
        {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

            // validate xml file by parser
            // that is: use a dtd file to validate the xml file
            dbf.setValidating(true);

            DocumentBuilder db = dbf.newDocumentBuilder();
            doc = db.parse(xmlFile);

            Element root = doc.getDocumentElement();
            NodeList nodes = root.getChildNodes();

            for (i = 0; i < nodes.getLength(); i++)
            {
                Node node = nodes.item(i);

                if (node.getNodeName().equals("#text"))
                {
                    continue;
                }

                if (node.getNodeName().equals(
                        ProtectedResource.PROPERTY_PROTECTED_RESOURCE))
                {
                    ProtectedResource pr = parseNode(node);
                    protectedResources.add(pr);
                }
            }
        } catch (ParserConfigurationException e)
        {
            log.error("parse acl-config.xml: " + e);
        } catch (IOException e)
        {
            log.error("parse  acl-config.xml: " + e);
        } catch (SAXException e)
        {
            log.error("parse acl-config.xml: " + e);
        }*/
        Right[] rights = rightDAO.findAllRight();
        for (int i = 0; i < rights.length; i++)
        {
            ProtectedResource pr = new ProtectedResource(rights[i].getBox(),rights[i].getDesc(),rights[i].getUrl()); 
            protectedResources.add(pr);
        }
    }

    /**
     * Read uri and desc from a protected-resource node
     * 
     * @param protectedResourceNode
     *            node of protected resource in xml file
     * @return ProtectedResources
     */
    private ProtectedResource parseNode(final Node protectedResourceNode)
    {
        String property;
        String value;
        NodeList nodes = protectedResourceNode.getChildNodes();
        String box = null;
        String url = null;
        String desc = null;

        for (int i = 0; i < nodes.getLength(); i++)
        {
            Node node = nodes.item(i);

            if (node.getNodeName().equals("#text"))
            {
                continue;
            }

            property = node.getNodeName();
            value = node.getFirstChild().getNodeValue();

            if (property.equals(ProtectedResource.PROPERTY_URL))
            {
                url = value;
            } else if (property.equals(ProtectedResource.PROPERTY_DESC))
            {
                desc = value;
            } else if (property.equals(ProtectedResource.PROPERTY_BOX))
            {
                box = value;
            }
        }

        return new ProtectedResource(box, desc, url);
    }
    /**
     * @return Returns the rightDAO.
     */
    public RightDAO getRightDAO()
    {
        return rightDAO;
    }
    /**
     * @param rightDAO The rightDAO to set.
     */
    public void setRightDAO(RightDAO rightDAO)
    {
        this.rightDAO = rightDAO;
    }
}